package com.weixiaodong.javabasic.冗余的ifelse的代替方式;

import com.weixiaodong.javabasic.冗余的ifelse的代替方式.工厂方式.OrderAdminRole;
import com.weixiaodong.javabasic.冗余的ifelse的代替方式.工厂方式.RoleFactory;
import com.weixiaodong.javabasic.冗余的ifelse的代替方式.枚举方式.RoleEnum;
import com.weixiaodong.javabasic.冗余的ifelse的代替方式.枚举方式.RoleOperation;
import com.weixiaodong.javabasic.冗余的ifelse的代替方式.策略模式.RoleContext;

import javax.management.relation.Role;

@SuppressWarnings("all")
public class MainTest {

    /**
     * 这一段出现了冗余的if-else的判断，如果权限种类非常多，这个if-else结构在实际开发中会比较难以维护
     * 一旦需要删除或则会添加新的权限，可能会动整个接口的代码，一般这种情况我们有三种代替模式：
     *  1. 枚举模式
     *  2. 工厂模式
     *  3. 策略模式
     * @param roleName
     * @return
     */
    public static String judge(String roleName) { // 根据角色判断用户权限
        String result = "";
        if ("ROLE_ROOT_ADMIN".equals(roleName)) {
            result = "ROLE_ROOT_ADMIN" + ": " + "has AAA permission";
        } else if ("ROLE_ORDER_ADMIN".equals(roleName)) {
            result = "ROLE_ORDER_ADMIN" + ": " + "has BBB permission";
        } else if ("ROLE_NORMAL".equals(roleName)) {
            result = "ROLE_NORMAL" + ": " + "has CCC permission";
        }
        return result;
    }

    /**
     * 这里传入的枚举类型的另外一大好处就是避免了用户的任意性字符串输入，如果指定的枚举类型不在定义的枚举类中，直接出现编译异常，可以提示用户
     * 输出错误，但是如果参数是字符串的化，这里的参数可以随意填写
     * @param roleEnum
     * @return
     */
    public static String judgeByEnum(RoleEnum roleEnum) {
        return roleEnum.op();
    }

    /**
     * 通过工厂模式实现，定义三个角色类并继承RoleOperation接口，各自实现自己的权限方法，然后在工厂中聚合定义的角色，初始化对应的权限
     * 当然这个映射关系可以选择对外暴露，也可以不对外暴露，根据实际要求实现，如果不对外暴露，就需要对外暴露一个可以获取权限的接口
     * @param roleEnum
     * @return
     */
    public static String judgeByFactory(RoleEnum roleEnum) {
        return RoleFactory.getPermission(roleEnum);
    }

    public static String judgeByContext(RoleOperation roleOperation) {
        RoleContext roleContext = new RoleContext(roleOperation);
        return roleContext.getPermission();
    }

    public static void main(String[] args) {
        // 测试枚举模式
        System.out.println(judgeByEnum(RoleEnum.ROLE_NORMAL));
        System.out.println(judgeByFactory(RoleEnum.ROLE_ORDER_ADMIN));
        System.out.println(judgeByContext(new OrderAdminRole(RoleEnum.ROLE_ORDER_ADMIN)));
    }
}
